/**
 * 
 */
package org.rico.sso.commons;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

/**
 * httpClient GET/POST util
 * @author rico
 *
 */
public class HttpClientUtil {

	/**
	 * @param url
	 * @return
	 * @throws IOException
	 */
	public static String httpGet(String url) throws IOException {
		return httpGet(url, null);
	}
	
	/**
	 * @param url
	 * @param params
	 * @return
	 * @throws IOException
	 */
	public static String httpGet(String url, Map<String, String> params) throws IOException {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			HttpGet httpget = new HttpGet(buildQuery(url, params));
			System.out.println("Executing request " + httpget.getRequestLine());

			// Create a custom response handler
			ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
				@Override
				public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
					int status = response.getStatusLine().getStatusCode();
					if (status >= 200 && status < 300) {
						HttpEntity entity = response.getEntity();
						return entity != null ? EntityUtils.toString(entity) : null;
					} else {
						throw new ClientProtocolException("Unexpected response status: " + status);
					}
				}
			};
			
			String responseBody = httpclient.execute(httpget, responseHandler);
			System.out.println("----------------------------------------");
			System.out.println(responseBody);
			
			return responseBody;
		} finally {
			httpclient.close();
		}
	}
	
	/**
	 * @param url
	 * @param params
	 * @return
	 */
	private static String buildQuery(String url, Map<String, String> params) {
		StringBuffer query = new StringBuffer(url);
		
		if(params==null || params.keySet()==null || params.keySet().isEmpty()) {
			return query.toString();
		}
		
		query.append("?");
		String split = "";
		for(Entry<String, String> entry : params.entrySet()) {
			query.append(split).append(entry.getKey()).append("=").append(entry.getValue());
			split = "&";
		}
		
		return query.toString();
	}
	
	/**
	 * @param url
	 * @return
	 * @throws IOException
	 */
	public static String httpPost(String url) throws IOException {
		return httpPost(url, null);
	}
	
	/**
	 * @param url
	 * @param params
	 * @return
	 * @throws IOException
	 */
	public static String httpPost(String url, Map<String, String> params) throws IOException {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		CloseableHttpResponse response = null;
		String responseBody = null;
		
		try {
			HttpPost httppost = new HttpPost(url);
			System.out.println("Executing request: " + httppost.getRequestLine());
			
			if(params != null) {
				UrlEncodedFormEntity entity = new UrlEncodedFormEntity(buildValuePairs(params));
				httppost.setEntity(entity);
			}
            
            response = httpclient.execute(httppost);
            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            
            responseBody = EntityUtils.toString(response.getEntity());
            System.out.println(responseBody);
		} finally {
			response.close();
			httpclient.close();
		}
		
		return responseBody;
	}
	
	/**
	 * @param params
	 * @return
	 */
	private static List<BasicNameValuePair> buildValuePairs(Map<String, String> params) {
		if(params==null || params.isEmpty()) {
			return null;
		}
		
		List<BasicNameValuePair> pairs = new ArrayList<>();
		for(Entry<String, String> entry : params.entrySet()) {
			BasicNameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue());
			pairs.add(pair);
		}
		
		return pairs;
	}

}
